/*
AI搜索：rust trait 泛型例子
1. 基本 Trait + 泛型
定义 Trait 并使用泛型
rust
复制
trait Printer<T> {
    fn print(&self, value: T);
}
Printer 是一个泛型 Trait，可以接受任意类型 T。

任何实现 Printer<T> 的类型，都必须提供 print(value: T) 方法。

为特定类型实现 Trait
rust
复制
struct ConsolePrinter;

impl Printer<String> for ConsolePrinter {
    fn print(&self, value: String) {
        println!("{}", value);
    }
}

impl Printer<i32> for ConsolePrinter {
    fn print(&self, value: i32) {
        println!("{}", value);
    }
}
ConsolePrinter 实现了 Printer<String> 和 Printer<i32>，可以打印 String 和 i32。

使用示例
rust
复制
fn main() {
    let printer = ConsolePrinter;
    printer.print("Hello".to_string());  // 打印 String
    printer.print(42);                  // 打印 i32
}
2. 泛型 Trait 约束（Trait Bound）
定义泛型函数，要求 T 实现某个 Trait
rust
复制
trait Greet {
    fn greet(&self);
}

struct Person;
impl Greet for Person {
    fn greet(&self) {
        println!("Hello!");
    }
}

fn say_hello<T: Greet>(item: T) {
    item.greet();
}
say_hello<T: Greet> 表示 T 必须实现 Greet Trait。

只有实现了 Greet 的类型才能调用 say_hello。

使用示例
rust
复制
fn main() {
    let person = Person;
    say_hello(person);  // 输出: "Hello!"
}
3. 多个 Trait 约束（+ 语法）
要求泛型 T 同时实现多个 Trait
rust
复制
trait Speak {
    fn speak(&self);
}

trait Walk {
    fn walk(&self);
}

struct Dog;
impl Speak for Dog {
    fn speak(&self) {
        println!("Woof!");
    }
}
impl Walk for Dog {
    fn walk(&self) {
        println!("Dog is walking...");
    }
}

fn do_actions<T: Speak + Walk>(animal: T) {
    animal.speak();
    animal.walk();
}
do_actions<T: Speak + Walk> 表示 T 必须同时实现 Speak 和 Walk。

使用示例
rust
复制
fn main() {
    let dog = Dog;
    do_actions(dog);  // 输出: "Woof!" 和 "Dog is walking..."
}
4. where 语法（更清晰的 Trait 约束）
当 Trait 约束较多时，可以用 where 提高可读性
rust
复制
fn complex_function<T, U>(a: T, b: U) -> String
where
    T: Speak + std::fmt::Debug,
    U: Walk + Clone,
{
    a.speak();
    println!("{:?}", a);
    b.walk();
    b.clone();
    "Done".to_string()
}
where 子句让函数签名更清晰，避免 <> 里塞太多内容。

使用示例
rust
复制
fn main() {
    let dog = Dog;
    let another_dog = Dog;
    complex_function(dog, another_dog);
}
5. Trait 作为返回值（impl Trait）
返回实现了某个 Trait 的类型
rust
复制
trait Animal {
    fn make_sound(&self);
}

struct Cat;
impl Animal for Cat {
    fn make_sound(&self) {
        println!("Meow!");
    }
}

fn get_animal() -> impl Animal {
    Cat
}
-> impl Animal 表示返回某个实现了 Animal 的类型（但具体类型在编译时确定）。

使用示例
rust
复制
fn main() {
    let animal = get_animal();
    animal.make_sound();  // 输出: "Meow!"
}
6. 动态分发（dyn Trait）
运行时多态（Trait 对象）
rust
复制
trait Shape {
    fn area(&self) -> f64;
}

struct Circle { radius: f64 }
impl Shape for Circle {
    fn area(&self) -> f64 {
        3.14 * self.radius * self.radius
    }
}

struct Square { side: f64 }
impl Shape for Square {
    fn area(&self) -> f64 {
        self.side * self.side
    }
}

fn print_area(shape: &dyn Shape) {
    println!("Area: {}", shape.area());
}
&dyn Shape 表示一个 Trait 对象，允许在运行时动态调用不同实现。

使用示例
rust
复制
fn main() {
    let circle = Circle { radius: 2.0 };
    let square = Square { side: 3.0 };
    print_area(&circle);  // 输出: "Area: 12.56"
    print_area(&square); // 输出: "Area: 9"
}
总结
场景	语法	用途
基本泛型 Trait	trait Printer<T>	让 Trait 支持泛型
Trait 约束	fn foo<T: Trait>(x: T)	限制泛型必须实现某个 Trait
多个 Trait 约束	T: Trait1 + Trait2	要求泛型实现多个 Trait
where 语法	where T: Trait	提高复杂约束的可读性
impl Trait 返回值	-> impl Trait	返回某个实现了 Trait 的类型
动态分发 (dyn)	&dyn Trait	运行时多态（Trait 对象）
这些技巧可以让你在 Rust 中更灵活地使用 Trait + 泛型，写出更通用、更安全的代码！
*/

/*
运行使用：RUST_BACKTRACE=1 cargo run

// 说明栈的释放顺序？先进后出？
{
    let x = 5;            // ----------+-- 'b
    let r = &x;           // --+-- 'a  |
    println!("r: {}", r); //   |       |
                          // --+       |
}                         // ----------+

现在函数签名表明对于某些生命周期 'a，函数会获取两个参数，他们都是与生命周期 'a 存在的一样长的字符串 slice。

*/

/*
ai解释：
'a 是一个生命周期参数，它表示 x 和 y 的引用必须至少存活 'a 这么久。
返回值的生命周期 'a 是 x 和 y 中较短的那个生命周期（Rust 编译器会自动推断）。
这意味着返回的 &str 不能比 x 或 y 中更短的那个活得更久。
string1 的生命周期 'a 更长，string2 的生命周期 'b 较短。
result 的生命周期是 'b（因为 longest 返回的生命周期是 x 和 y 中较短的那个）。
一旦 string2 离开作用域（'b 结束），result 就不能再使用。
*/


trait Displayable {
    fn display(&self);
}
impl Displayable for i32 {
    fn display(&self) { println!("i32: {}", self); }
}
impl Displayable for String {
    fn display(&self) { println!("String: {}", self); }
}
impl Displayable for &str {
    fn display(&self) { println!("str: {}", self); }
}

fn my_show<T: Displayable>(item: T) {
    item.display();
}

fn main() {
    {
        let tmpi32 = 123;
        tmpi32.display();
        24.display();
        "abc".display();
        let tmpstr = String::from("dc");
        tmpstr.display();
    }
    {
        my_show(256);
        my_show("ef");
        my_show(String::from("gh"));
        // my_show(1.2);
    }
}

// fn type_str<T>(_val: &T) -> & 'static str {
//     std::any::type_name::<T>()
// }
